#include "Particle.h"
#include "Emitter.h"

///render offset
#include "Camera.h"

Particle::Particle( void )
{ 
}


Particle::~Particle(void)
{
}

void Particle::Initalize( void )
{
	isActive = false;

	ImageID = emitter->GetImageID();
	ImageWidth = (float)CSGD_TextureManager::GetInstance()->GetTextureWidth(ImageID);
	ImageHeight = (float)CSGD_TextureManager::GetInstance()->GetTextureHeight(ImageID);

	curRotation = emitter->GetInitialRotation();

	if(emitter->GetInitialScale() > emitter->GetFinalScale())
		curScale = RandomFloat( emitter->GetFinalScale(), emitter->GetInitialScale() );
	else
		curScale = RandomFloat( emitter->GetInitialScale(), emitter->GetFinalScale() );
	
	timeAlive = 0.0f;
	lifetime = RandomFloat( emitter->GetLifetimeMin(), emitter->GetLifetimeMax() );
	
	RandomFloat(emitter->GetSpeedMin(), emitter->GetSpeedMax());

	tVector2D direction = {0, -1};
	float headingAngle = RandomFloat(emitter->GetEmitterRotation() - (.5f * emitter->GetAngleRange()), emitter->GetEmitterRotation() + (.5f * emitter->GetAngleRange()) );
	float headingInRadians = headingAngle * D3DX_PI / 180.0f;

	direction = Vector2DRotate( direction, headingInRadians );

	direction = Vector2DNormalize( direction );

	curVelocity = direction * RandomFloat(emitter->GetSpeedMin(), emitter->GetSpeedMax());

	rotupdate = (emitter->GetFinalRotation() - emitter->GetInitialRotation()) / lifetime;
	scaleupdate = (emitter->GetFinalScale() - emitter->GetInitialScale()) / lifetime;

	iclra = emitter->GetInitClrA();
	iclrr = emitter->GetInitClrR();
	iclrg = emitter->GetInitClrG();
	iclrb = emitter->GetInitClrB();
	fclra = emitter->GetFinalClrA();
	fclrr = emitter->GetFinalClrR();
	fclrg = emitter->GetFinalClrG();
	fclrb = emitter->GetFinalClrB();


	if(strcmp(emitter->GetShape().c_str(), "Line"))
	{
		tVector2D center = emitter->GetPosition();

		int r = (int)(center.fX + emitter->GetOffsetX());
		int r2 = (int)(center.fX - emitter->GetOffsetX() + 1);
		tVector2D ParticlePreRotation = { (float)(rand()%(r - r2)) + (int)(center.fX - emitter->GetOffsetX()), center.fY };


		tVector2D CenterToParticle = { ParticlePreRotation.fX - center.fX, ParticlePreRotation.fX - center.fX };

		float RotationInRadians = emitter->GetEmitterRotation() * D3DX_PI / 180;

		CenterToParticle = Vector2DRotate( CenterToParticle, RotationInRadians );

		tVector2D ParticleAfterRotation = { center.fX + CenterToParticle.fX, center.fY + CenterToParticle.fY };

		curPosX = ParticleAfterRotation.fX;
		curPosY = ParticleAfterRotation.fY;
	}
	else if(strcmp(emitter->GetShape().c_str(), "Square"))
	{
		tVector2D center = emitter->GetPosition();

		tVector2D ParticlePreRotation = { (float)(rand()%((int)(center.fX + emitter->GetOffsetX()) - (int)(center.fX - emitter->GetOffsetX()) + 1)) + (center.fX - emitter->GetOffsetX()), 
			(float)(rand()%((int)(center.fY + emitter->GetOffsetY()) - (int)(center.fY - emitter->GetOffsetY()) + 1 )) + (int)(center.fY - emitter->GetOffsetX()) };


		tVector2D CenterToParticle = { ParticlePreRotation.fX - center.fX, ParticlePreRotation.fX - center.fX };

		float RotationInRadians = emitter->GetEmitterRotation() * D3DX_PI / 180;

		CenterToParticle = Vector2DRotate( CenterToParticle, RotationInRadians );

		tVector2D ParticleAfterRotation = { center.fX + CenterToParticle.fX, center.fY + CenterToParticle.fY };

		curPosX = ParticleAfterRotation.fX;
		curPosY = ParticleAfterRotation.fY;
	}
	else if(strcmp(emitter->GetShape().c_str(), "Circle"))
	{
		float random = rand()/(float)RAND_MAX;
		curPosX = (cos(random) * emitter->GetOffsetX()) + emitter->GetPosition().fX;
		curPosY = (sin(random) * emitter->GetOffsetY()) + emitter->GetPosition().fY;
	}
}

void Particle::Update(float deltaTime)
{
	timeAlive += deltaTime;

	if(timeAlive > lifetime )
		this->Initalize();
	else
	{
		if(emitter->GetGravity())
			curVelocity.fY += .5f;

		curPosX += curVelocity.fX * deltaTime;
		curPosY += curVelocity.fY * deltaTime;

		curScale += scaleupdate * deltaTime;
		curRotation += rotupdate * deltaTime;

		int aval = (int)Lerp( (float)iclra, (float)fclra, timeAlive/lifetime );
		int rval = (int)Lerp( (float)iclrr, (float)fclrr, timeAlive/lifetime );
		int gval = (int)Lerp( (float)iclrg, (float)fclrg, timeAlive/lifetime );
		int bval = (int)Lerp( (float)iclrb, (float)fclrb, timeAlive/lifetime );

		curColor = D3DCOLOR_ARGB(aval, rval, gval, bval);
	}
}

void Particle::Render( void ) const
{
	RECT source = { 0, 0, (long)ImageWidth, (long)ImageHeight };
	CSGD_TextureManager::GetInstance()->Draw(ImageID, 
		(int)(curPosX- Camera::GetInstance()->OffsetX()),
		(int)(curPosY - Camera::GetInstance()->OffsetY()), curScale, curScale, &source, (ImageWidth * curScale ) / 2, (ImageHeight * curScale ) / 2, curRotation, curColor);
}

void Particle::SetEmitter( Emitter* Owner )
{
	this->emitter = Owner;
}